home *** CD-ROM | disk | FTP | other *** search
- /* FilterSecondOrderZero.c */
- /*****************************************************************************/
- /* */
- /* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
- /* Copyright (C) 1994 Thomas R. Lawrence */
- /* */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to the Free Software */
- /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* */
- /* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
- /* */
- /*****************************************************************************/
-
- /* Based on material from pages 184-190 of */
- /* Dodge, Charles and Jerse, Thomas A. */
- /* Computer Music: Synthesis, Composition, and Performance */
- /* Schirmer Books, New York, 1985 */
-
- #include "MiscInfo.h"
- #include "Audit.h"
- #include "Debug.h"
- #include "Definitions.h"
-
- #include "FilterSecondOrderZero.h"
- #include "Memory.h"
- #include "FloatingPoint.h"
-
-
- struct SecondOrderZeroRec
- {
- /* link */
- SecondOrderZeroRec* Next;
-
- /* state variables */
- float Xm1;
- float Xm2;
-
- /* coefficients */
- float A0;
- float A1;
- float A2;
- };
-
-
- static SecondOrderZeroRec* FreeList = NIL;
-
-
- /* flush free list */
- void FlushCachedSecondOrderZeroStuff(void)
- {
- while (FreeList != NIL)
- {
- SecondOrderZeroRec* Temp;
-
- Temp = FreeList;
- FreeList = FreeList->Next;
- ReleasePtr((char*)Temp);
- }
- }
-
-
- /* create a new filter record */
- SecondOrderZeroRec* NewSecondOrderZero(void)
- {
- SecondOrderZeroRec* Filter;
-
- if (FreeList != NIL)
- {
- Filter = FreeList;
- FreeList = FreeList->Next;
- }
- else
- {
- Filter = (SecondOrderZeroRec*)AllocPtrCanFail(sizeof(SecondOrderZeroRec),
- "SecondOrderZeroRec");
- if (Filter == NIL)
- {
- return NIL;
- }
- }
- Filter->Xm1 = 0;
- Filter->Xm2 = 0;
- return Filter;
- }
-
-
- /* dispose filter record */
- void DisposeSecondOrderZero(SecondOrderZeroRec* Filter)
- {
- CheckPtrExistence(Filter);
- Filter->Next = FreeList;
- FreeList = Filter;
- }
-
-
- /* adjust filter coefficients */
- void SetSecondOrderZeroCoefficients(SecondOrderZeroRec* Filter,
- float Cutoff, float Bandwidth, FilterScalings Scaling,
- long SamplingRate)
- {
- float C2;
- float C1;
- float D;
-
- CheckPtrExistence(Filter);
- C2 = DEXP(-6.28318530717958648 * Bandwidth / SamplingRate);
- C1 = (-4*C2/(1 + C2)) * DCOS(6.28318530717958648 * Cutoff / SamplingRate);
- switch (Scaling)
- {
- default:
- EXECUTE(PRERR(ForceAbort,"SetSecondOrderZeroCoefficients: unknown scaling"));
- break;
- case eFilterDefaultScaling:
- D = 1;
- break;
- case eFilterZeroGain1:
- D = 1 + C1 + C2;
- break;
- }
- Filter->A0 = 1 / D;
- Filter->A1 = C1 / D;
- Filter->A2 = C2 / D;
- }
-
-
- /* apply filter to a sample value */
- float ApplySecondOrderZero(SecondOrderZeroRec* Filter, float Xin)
- {
- float Y;
-
- CheckPtrExistence(Filter);
- Y = Filter->A0 * Xin + Filter->A1 * Filter->Xm1 + Filter->A2 * Filter->Xm2;
- Filter->Xm2 = Filter->Xm1;
- Filter->Xm1 = Xin;
- return Y;
- }
-